package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.zhijian.medical.dao.local.RoutinePathologyRsMapper;
import com.zhijian.medical.entity.po.*;
import com.zhijian.medical.entity.vo.request.*;
import com.zhijian.medical.entity.vo.response.*;
import com.zhijian.medical.enums.RoutineHistoryEnum;
import com.zhijian.medical.enums.RoutinePathologySampleStepEnum;
import com.zhijian.medical.enums.RoutineRsEnum;
import com.zhijian.medical.enums.RoutineTsEnum;
import com.zhijian.medical.service.*;
import com.zhijian.util.page.Page;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.hutool.core.collection.CollectionUtil;
import com.zhijian.util.AssertUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 常规病理-染色业务处理层
 * 
 * @author auto
 * @version: 1.0
 * @date 2024-07-26 16:47:47
 */
@Slf4j
@Service
public class RoutinePathologyRsServiceImpl implements RoutinePathologyRsService {

	@Autowired
    private RoutinePathologyRsMapper mapper;

    @Autowired
    private RoutineSingleSampleService singleSampleService;

    @Autowired
    private RoutineHistoryService historyService;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private RoutinePathologyTsSjService tsSjService;

    @Autowired
    private DeviceAdjustRecordService adjustRecordService;

    @Autowired
    private RoutineStepService stepService;

    @Autowired
    private RoutineStepRecordService stepRecordService;

    @Autowired
    private CacheService cacheService;

    @Autowired
    private RoutineQcService qcService;

    @Autowired
    private RoutinePatientService patientService;
    @Autowired
    private SpecialInstructionService specialInstructionService;

    @Override
    public RoutinePathologyRs selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public RoutinePathologyRsVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public Long insert(RoutinePathologyRs routinePathologyRs) {
        Date now = new Date();
        routinePathologyRs.setCreateTime(now);
        routinePathologyRs.setUpdateTime(now);
        return mapper.insert(routinePathologyRs) > 0 ? routinePathologyRs.getId() : 0L;
    }

    @Override
    public Long insertSelective(RoutinePathologyRs routinePathologyRs) {
        Date now = new Date();
        routinePathologyRs.setCreateTime(now);
        routinePathologyRs.setUpdateTime(now);
        return mapper.insertSelective(routinePathologyRs) > 0 ? routinePathologyRs.getId() : 0L;
    }

    @Override
    public boolean update(RoutinePathologyRs routinePathologyRs) {
        Date now = new Date();
        routinePathologyRs.setUpdateTime(now);
        return mapper.updateByPrimaryKey(routinePathologyRs) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(RoutinePathologyRs record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Override
    public boolean save(RoutinePathologyRsSaveOrUpdateVo saveOrUpdateVo) {
        RoutinePathologyRs routinePathologyRs = new RoutinePathologyRs();
        BeanUtils.copyProperties(saveOrUpdateVo, routinePathologyRs);
        return this.insert(routinePathologyRs) != 0;
    }

    @Override
    public boolean modify(RoutinePathologyRsSaveOrUpdateVo saveOrUpdateVo) {
        RoutinePathologyRs old = this.selectById(saveOrUpdateVo.getId());
        AssertUtil.notNull(old, "此数据不存在或者已被删除");
        RoutinePathologyRs routinePathologyRs = new RoutinePathologyRs();
        BeanUtils.copyProperties(saveOrUpdateVo, routinePathologyRs);
        return this.update(routinePathologyRs);
    }

    @Override
    public RoutinePathologyRsVo selectOne(RoutinePathologyRsSearchVo routinePathologyRsSearchVo) {
        return mapper.selectOne(routinePathologyRsSearchVo);
     }

    @Override
    public Integer count(RoutinePathologyRsSearchVo routinePathologyRsSearchVo) {
        return mapper.count(routinePathologyRsSearchVo);
    }

    @Override
    public List<RoutinePathologyRsVo> selectList(RoutinePathologyRsSearchVo routinePathologyRsSearchVo) {
        return mapper.selectList(routinePathologyRsSearchVo);
    }

    @Override
    public Page<RoutinePathologyRsVo> selectPage(RoutinePathologyRsSearchVo routinePathologyRsSearchVo) {
        AssertUtil.check(Objects.isNull(routinePathologyRsSearchVo.getPageNum()) || Objects.isNull(routinePathologyRsSearchVo.getPageSize()), "分页参数不能为空");
        //先直接查总数
        int count = count(routinePathologyRsSearchVo);
        //分页
        Page<RoutinePathologyRsVo> page = new Page<>(true, count, routinePathologyRsSearchVo.getPageNum(), routinePathologyRsSearchVo.getPageSize());
        routinePathologyRsSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<RoutinePathologyRsVo> responseVos = this.selectList(routinePathologyRsSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<RoutinePathologyRs> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Override
    public void deleteByCondition(RoutinePathologyRsSearchVo routinePathologyRsSearchVo) {
        //慎重用此方法！！
        mapper.deleteByCondition(routinePathologyRsSearchVo);
    }


    @Transactional(rollbackFor = Exception.class, value = "localTransactionManager")
    @Override
    public boolean inputNums(String numbers) {
        // 校验重复--暂时关闭（影响其他地方的染色）
//        Integer count = this.count(RoutinePathologyRsSearchVo.builder().sample(numbers).build());
//        com.zhijian.medical.util.AssertUtil.check(count > 0, "信息已录入");
        // 记录染色历史
        List<RoutineSingleSampleVo> routineSingleSampleVos = singleSampleService.selectList(RoutineSingleSampleSearchVo.builder().rsjCode(numbers).build());
        com.zhijian.medical.util.AssertUtil.check(CollUtil.isEmpty(routineSingleSampleVos), "未查询到此染色架编号");
        List<RoutineHistory> entities = new ArrayList<>();
        Date nowDate = new Date();
        for (RoutineSingleSampleVo vo : routineSingleSampleVos) {
            RoutineHistory history = new RoutineHistory();
            history.setUpdateTime(nowDate);
            history.setCreateTime(nowDate);
            history.setNumber(vo.getNumber());
            history.setStep(RoutineHistoryEnum.RS.getCode().byteValue());
            history.setSampleId(vo.getId());
            entities.add(history);

//            Integer count1 = historyService.count(RoutineHistorySearchVo.builder()
//                    .number(vo.getNumber())
//                     .step(RoutineHistoryEnum.RS.getCode().byteValue())
//                    .build());
//            com.zhijian.medical.util.AssertUtil.check(count1 > 0, "信息已录入");
        }
        historyService.insertBatch(entities);
        // 修改染色状态
        // 获取预计完成时间 52分钟50秒
        // 染色流程包括：二甲苯①，10min；二甲苯②，10min；无水乙醇①，1min；无水乙醇②，1min；95%乙醇①，1min；95%乙醇②，1min；
        // 80%乙醇①，1min；80%乙醇②，1min；自来水洗，1min；苏木素，2min；自来水洗，1min；1%盐酸酒精，30s；自来水洗，5min；伊红，1min；
        // 自来水洗，30s；85%乙醇，20s；90%乙醇，30s；95%乙醇①，1min；95%乙醇②，1min；无水乙醇①，2min；无水乙醇②，2min；二甲苯①，2min；
        // 二甲苯②，2min；封片，5min。
        DateTime endTime = DateUtil.offset(nowDate, DateField.SECOND, 52*60 + 50);

        this.insert(RoutinePathologyRs.builder()
                .step(RoutineRsEnum.ONE.getCode().byteValue())
                .endTime(endTime)
                .sample(numbers)
                .leftTime(14*60*60 + "")
                .rsybs(routineSingleSampleVos.size())
                .rsybsDev(0)
                .build());
        // 记录设备最大数
        String s = cacheService.get("gl_ranse_count");
        if (StringUtils.isEmpty(s)) {
            cacheService.set("gl_ranse_count", routineSingleSampleVos.size() + "");
        } else {
            Integer devCount = Integer.parseInt(s) + routineSingleSampleVos.size();
            cacheService.set("gl_ranse_count", devCount + "");
        }
        // 用作 redis 倒计时
        cacheService.setex("gl_step_rs_time/" + numbers, 1*60, "1");

        // 获取病理号
        String conventionPathologyNumber = qcService.selectById(routineSingleSampleVos.get(0).getQcId()).getConventionPathologyNumber();
        // 修改状态为染色
        RoutineStepVo routineStepVo = stepService.selectOne(RoutineStepSearchVo.builder().conventionPathologyNumber(conventionPathologyNumber).build());
        if (routineStepVo.getStep() < RoutinePathologySampleStepEnum.RS.getCode().byteValue()) {
            String contetnt = "在实验室染色";
            stepService.updateStepByNums(conventionPathologyNumber, contetnt, RoutinePathologySampleStepEnum.RS.getCode().byteValue());
            stepRecordService.insert(RoutineStepRecord.builder()
                    .conventionPathologyNumber(conventionPathologyNumber)
                    .step(RoutinePathologySampleStepEnum.RS.getCode().byteValue())
                    .content(contetnt)
                    .build());
        }
        return true;
    }

    @Autowired
    DeviceAdjustRecordService deviceAdjustRecordService;

    @Override
    public RoutinePathologyRsVo pathologyInfo(String numbers) {
        RoutinePathologyRsVo rsVo = this.selectOne(RoutinePathologyRsSearchVo.builder().sample(numbers).build());
        Long ttl = cacheService.ttl("gl_step_rs_time/" + rsVo.getSample());
        rsVo.setLeftTime(ttl > 0 ? String.valueOf(ttl) : "0");
        // 查找设备信息
        List<Device> devices = deviceService.selectListByType("染色");
        DeviceTsVo deviceTsVo = new DeviceTsVo();
        if (CollUtil.isNotEmpty(devices)) {
            BeanUtils.copyProperties(devices.get(0), deviceTsVo);
            // 默认维修时间是现在时间- 3 个月
            Date adjustDate = DateUtil.offset(new Date(), DateField.MONTH, -3);
            String adjustTime = DateUtil.formatDateTime(adjustDate);
            // 默认下次维修时间是现在时间+8个月
            adjustDate = DateUtil.offset(new Date(), DateField.MONTH, 8);
            String nextAdjustTime = DateUtil.formatDateTime(adjustDate);
            // 查找维修记录
            List<DeviceAdjustRecordVo> deviceAdjustRecordVos = adjustRecordService.selectList(DeviceAdjustRecordSearchVo.builder().deviceId(deviceTsVo.getId()).build());
            // 有记录
            if (CollUtil.isNotEmpty(deviceAdjustRecordVos)) {
                adjustTime = deviceAdjustRecordVos.get(0).getDate() + " 00:00:00";
                //adjustTime = deviceAdjustRecordVos.get(0).getCreateTime();
                adjustDate = DateUtil.parse(adjustTime);
                nextAdjustTime = DateUtil.formatDateTime(DateUtil.offset(adjustDate, DateField.MONTH, 11));
            }
            deviceTsVo.setJzrq(adjustTime);
            deviceTsVo.setXcjzrq(nextAdjustTime);
        }
        rsVo.setDeviceTsVo(deviceTsVo);
        // 查找试剂信息
        List<RoutinePathologyTsSjVo> routinePathologyTsSjVos = tsSjService.selectList(RoutinePathologyTsSjSearchVo.builder().tsId(2L).build());
        rsVo.setSjVoList(routinePathologyTsSjVos);
        // 获取设备最大值
        String s = cacheService.get("gl_ranse_count");
        rsVo.setRsybsDev(Integer.parseInt(s));

        rsVo.setStepEnums(RoutineRsEnum.getMap());
        // 获取特殊医嘱
        RoutineSingleSampleVo routineSingleSampleVo = singleSampleService.selectOne(RoutineSingleSampleSearchVo.builder().rsjCode(numbers).build());
        List<SpecialInstructionVo> specialInstructionVos = specialInstructionService.selectList(SpecialInstructionSearchVo.builder().waxBlock(routineSingleSampleVo.getNumber()).build());
        rsVo.setSpecialInstructionVos(specialInstructionVos);
        return rsVo;
    }

    @Override
    public List<RoutineSingleSampleRsVo> pathologySampleRsInfo() {
        List<RoutineSingleSampleRsVo>  singleSampleRsVos = new ArrayList<>();
        // 获取所有的染色信息
        List<RoutinePathologyRsVo> rsVos = this.selectList(RoutinePathologyRsSearchVo.builder().build());
        for (RoutinePathologyRsVo rsVo: rsVos) {
            // 筛掉已完成的记录
            if (rsVo.getStep().equals(RoutineRsEnum.OVER.getCode().byteValue())) {
                continue;
            }
            RoutineSingleSampleRsVo sampleRsVo = new RoutineSingleSampleRsVo();
            RoutineSingleSampleVo sampleVo = singleSampleService.selectOne(RoutineSingleSampleSearchVo.builder().rsjCode(rsVo.getSample()).build());
            sampleRsVo.setNumber(sampleVo.getNumber());
            sampleRsVo.setName(sampleVo.getName());
            sampleRsVo.setRsjCode(sampleVo.getRsjCode());
            // 根据取材编号找到病理号
            RoutineQc routineQc = qcService.selectById(sampleVo.getQcId());
            RoutinePatientVo routinePatientVo = patientService.selectOne(RoutinePatientSearchVo.builder()
                    .conventionPathologyNumber(routineQc.getConventionPathologyNumber())
                    .build());
            sampleRsVo.setPatientName(routinePatientVo.getName());
            singleSampleRsVos.add(sampleRsVo);
        }
        return singleSampleRsVos;
    }
}